/**
This file defines asm functions.
**/


.global arch_save_curr_context
///**
// * @brief save current task's context
// * 
// * @param to_save_old_sp the addr to save the old task's stack, usually the
// *                       address of ksp in task control block
// * @return int zero if return to the task, else means switching done.
// */
//int arch_save_curr_context(address to_save_old_sp);
arch_save_curr_context:
    addi sp,  sp, -8*23
    sd   sp,  0(a0)
    sd   x0,  8*0(sp) //mark as partial type
    sd   s0,  8*1(sp)
    sd   s1,  8*2(sp)
    sd   s2,  8*3(sp)
    sd   s3,  8*4(sp)
    sd   s4,  8*5(sp)
    sd   s5,  8*6(sp)
    sd   s6,  8*7(sp)
    sd   s7,  8*8(sp)
    sd   s8,  8*9(sp)
    sd   s9,  8*10(sp)
    sd   s10, 8*11(sp)
    sd   s11, 8*12(sp)

    sd   t0,  8*13(sp)
    sd   t1,  8*14(sp)
    sd   t2,  8*15(sp)
    sd   t3,  8*16(sp)
    sd   t4,  8*17(sp)
    sd   t5,  8*18(sp)
    sd   t6,  8*19(sp)
    
    sd   ra,  8*20(sp)
    sd   gp,  8*21(sp)
    sd   tp,  8*22(sp)
    li   a0,  0x1
    ret


.global arch_switch_to_task
///**
// * @brief execute actual context switching
// * 
// * @param new_sp the new task's stak
// * @param to_save_old_sp the addr to save the old task's stack, usually the
// *                       address of ksp in task control block
// */
//void arch_switch_to_task(StackPointer new_sp);
.global arch_switch_to_task
arch_switch_to_task:
    mv   sp,  a0
    ld   t1,  0(sp)
    beq  t1,  x0, partial_type
    full_type:
    ld   a0,  8*1(sp)
    ld   a1,  8*2(sp)
    ld   a2,  8*3(sp)
    ld   a3,  8*4(sp)
    ld   a4,  8*5(sp)
    ld   a5,  8*6(sp)
    ld   a6,  8*7(sp)
    ld   a7,  8*8(sp)

    ld   s0,  8*9(sp)
    ld   s1,  8*10(sp)
    ld   s2,  8*11(sp)
    ld   s3,  8*12(sp)
    ld   s4,  8*13(sp)
    ld   s5,  8*14(sp)
    ld   s6,  8*15(sp)
    ld   s7,  8*16(sp)
    ld   s8,  8*17(sp)
    ld   s9,  8*18(sp)
    ld   s10, 8*19(sp)
    ld   s11, 8*20(sp)

    ld   t0,  8*21(sp)
    ld   t1,  8*22(sp)
    ld   t2,  8*23(sp)
    ld   t3,  8*24(sp)
    ld   t4,  8*25(sp)
    ld   t5,  8*26(sp)
    ld   t6,  8*27(sp)

    ld   ra,  8*28(sp)
    ld   gp,  8*29(sp)
    ld   tp,  8*30(sp)
    ld   t0,  8*31(sp)
    addi sp, sp, 8*32
    mv   ra, t0
    ret
    partial_type:
    ld   s0,  8*1(sp)
    ld   s1,  8*2(sp)
    ld   s2,  8*3(sp)
    ld   s3,  8*4(sp)
    ld   s4,  8*5(sp)
    ld   s5,  8*6(sp)
    ld   s6,  8*7(sp)
    ld   s7,  8*8(sp)
    ld   s8,  8*9(sp)
    ld   s9,  8*10(sp)
    ld   s10, 8*11(sp)
    ld   s11, 8*12(sp)

    ld   t0,  8*13(sp)
    ld   t1,  8*14(sp)
    ld   t2,  8*15(sp)
    ld   t3,  8*16(sp)
    ld   t4,  8*17(sp)
    ld   t5,  8*18(sp)
    ld   t6,  8*19(sp)

    ld   ra,  8*20(sp)
    ld   gp,  8*21(sp)
    ld   tp,  8*22(sp)
    addi sp,  sp, 8*23
    mv   a0,  x0 ////mark that in return control flow
    ret